<?php
/**
 * Created by PhpStorm.
 * User: user1
 * Date: 2018/9/3
 * Time: 11:33
 */

namespace app\service;


use app\service\model\AdminAuthorityModel;
use app\service\model\AdminRoleModel;
use think\Db;
use think\Exception;
use think\facade\Cache;
use think\facade\Request;
use app\common\model\AdminAuthority as AuthModel;
use app\common\model\AdminRole as RoleModel;

class Jurisdiction
{
    private static $model;

    /**
     * 获取管理员的导航数据
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws exception\ApiException
     */
    public static function getShowMenu() {
        $admin = Token::checkAdminToken();
        $cache_key = 'admin_' . $admin['username'] . '_' . $admin['id'] . '_menu';
        if (!$menu = cache($cache_key)) {
            $auths = (AdminAuthorityModel::where("is_nav", '=', 1)->order('sort', 'desc')->select())->toArray(); // 获取所有权限
            $auths = self::list_to_tree($auths); // 将分类列表数据转换为无限极树状结构
//            halt(self::getJurisdiction($admin));
            $jurisdiction = explode(',', self::getJurisdiction($admin)); // 管理员已有权限

            $menu = json_encode(self::getMenuByAdminJurisdiction($auths, $jurisdiction)); // 根据权限获取导航数据
            cache($cache_key, $menu, null, 'admin_cache');
        }
//        print_R(json_decode($menu, true));die;
        return json_decode($menu, true);
    }

    /**
     * 根据条件获取权限数据
     * @param int $role_id
     * @param string $authIds
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getAllAuth($role_id = 0, $authIds = ''): array
    {
        $auths = (AdminAuthorityModel::where(function ($query) use($authIds) {
            if($authIds) {
                $query->where('id', 'in', $authIds);
            }
        })->order('sort desc')->select())->toArray(); // 获取所有权限
        if ($role_id > 0) {
            // 获取当前角色已有的权限
            $roleAuthIds = AdminRoleModel::find($role_id)->authoritys;

            // 检查权限是否需要选中
            self::checkAuthIsChecked($auths, $roleAuthIds);
        }

        $auths = self::list_to_tree($auths, 'id', 'pid'); // 将分类列表数据转换为无限极树状结构
        return $auths;
    }

    /**
     * 检查权限是否需要被选中
     * @param $auths
     * @param $authIds
     */
    private static function checkAuthIsChecked(&$auths, $authIds) {
        $authIds = explode(',', $authIds);
        foreach ($auths as &$v) {
            if (in_array($v['id'], $authIds)) {
                $v['checked'] = 1;
            } else {
                $v['checked'] = 0;
            }
        }
    }

    /**
     * 把返回的数据集转换成Tree
     * @param $list
     * @param string $pk
     * @param string $pid
     * @param string $child
     * @param int $root
     * @return array
     */
    public static function list_to_tree($list, $pk='id', $pid = 'pid', $child = 'child', $root = 0): array
    {
        // 创建Tree
        $tree = array();
        if(is_array($list)) {
            // 创建基于主键的数组引用
            foreach ($list as $key => $data) {
                $refer[$data[$pk]] =& $list[$key];
            }
            foreach ($list as $key => $data) {
                // 判断是否存在parent
                $parentId =  $data[$pid];
                if ($root == $parentId) {
                    $tree[] =& $list[$key];
                }else{
                    if (isset($refer[$parentId])) {
                        $parent =& $refer[$parentId];
                        $parent[$child][] =& $list[$key];
                    }
                }
            }
        }
        return $tree;
    }

    /**
     * 根据管理员权限获取导航数据
     * @param $auths
     * @param $jurisdiction
     * @return mixed
     */
    public static function getMenuByAdminJurisdiction($auths, $jurisdiction) {
        foreach ($auths as $k => $v) {
            if (isset($v['child'])) {
                foreach ($v['child'] as $lk => $lv) {
                    if (!in_array($lv['id'], $jurisdiction) && session('admin.username') != 'admin') {
                        unset($auths[$k]['child'][$lk]);
                    } else {
                        if (isset($lv['child'])) {
                            foreach ($lv['child'] as $sk => $sv) {
                                if (!in_array($sv['id'], $jurisdiction) && session('admin.username') != 'admin') {
                                    unset($auths[$k]['child'][$lk]['child'][$sk]);
                                }
                            }
                        }
                    }
                }
            }
            if ((!isset($v['child']) || !$auths[$k]['child'])) {
                unset($auths[$k]);
            }
        }
        return $auths;
    }

    /**
     * 创建管理员权限缓存
     * @param $role_ids
     * @param $admin_id
     * @param $admin_username
     * @return array|string
     */
    public static function createJurisdictionCache($role_ids, $admin_id, $admin_username) {

        $authIds = AdminRoleModel::getAuthIds($role_ids);
//        echo 123;
        // 权限信息写入缓存
        cache('admin_' . $admin_username . '_' . $admin_id . '_jurisdiction', $authIds, null, 'admin_cache');

        return $authIds;
    }

    /**
     * 获取当前管理员的权限
     * @param $admin
     * @return mixed|string
     */
    public static function getJurisdiction($admin) {
        if (!$jurisdiction = cache('admin_' . $admin['username'] . '_' . $admin['id'] . '_jurisdiction')) {

            $jurisdiction = self::createJurisdictionCache($admin['roles'], $admin['id'], $admin['username']);
        }
        return $jurisdiction;
    }
}